﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Kiiro.Common.Utility;
using Kiiro.Common.Entities;
using Kiiro.Logging;
using Kiiro.Model;
using Kiiro.SiteDefinition.Core;
using Microsoft.SharePoint;

namespace Kiiro.SiteDefinition.ControlTemplates
{
    public partial class Filter : KiiroUserControl
    {
        public EntityType EntityType { get; set; }

        public List<BaseEntity> Entities { get; set; }

        private List<SPField> FilterableColumns { get; set; }

        private static List<string> KiiroUserIdColumns = new List<string>{ 
            Constants.WorkFieldNames.AssignedToList,
            Constants.ProjectFieldNames.ProjectManagerIds
        };

        private static List<string> KiiroDefaultColumnsWork = new List<string>{
            Constants.WorkFieldNames.AssignedToList,
            Constants.WorkFieldNames.EndDate,
            Constants.WorkFieldNames.StartDate,
            Constants.WorkFieldNames.Status,
            Constants.WorkFieldNames.WorkItemType
        };

        private static List<string> KiiroDefaultColumnsProject = new List<string>{
            Constants.ProjectFieldNames.EndDate,
            Constants.ProjectFieldNames.ProjectManagerIds,
            Constants.ProjectFieldNames.StartDate
        };

        private Dictionary<string, string> KiiroDisplayNames = new Dictionary<string, string> ( );

        private void LoadFilters ( )
        {
            if ( Entities != null && Entities.Count > 0 )
            {
                KiiroDisplayNames.Add ( Constants.WorkFieldNames.AssignedToList, "Assigned To" );
                KiiroDisplayNames.Add ( Constants.WorkFieldNames.EndDate, "Due Date" );
                KiiroDisplayNames.Add ( Constants.WorkFieldNames.StartDate, "Start Date" );
                KiiroDisplayNames.Add ( Constants.WorkFieldNames.Status, "Status" );
                KiiroDisplayNames.Add ( Constants.WorkFieldNames.WorkItemType, "Type" );
                KiiroDisplayNames.Add ( Constants.ProjectFieldNames.EndDate, "End Date" );
                KiiroDisplayNames.Add ( Constants.ProjectFieldNames.ProjectManagerIds, "Project Manager" );
                KiiroDisplayNames.Add ( Constants.ProjectFieldNames.StartDate, "Start Date" );

                DropDownList master = new DropDownList { ID = "Field", CssClass = "Field" };
                pnlFilters.Controls.Add ( master );
                pnlFilters.Controls.Add ( new Literal { Text = "<span class='conjunction'>is </span>" } );

                if ( EntityType == EntityType.Work )
                    LoadFilterableColumns ( Constants.SPContentTypeIds.Work );
                else if ( EntityType == EntityType.Project )
                    LoadFilterableColumns ( Constants.SPContentTypeIds.Project );

                if ( FilterableColumns != null )
                {
                    foreach ( SPField field in FilterableColumns )
                    {
                        string childCssClass = EnsureChildFilter ( field );
                        if ( pnlFilters.FindControl ( childCssClass ) != null )
                        {
                            string value = field.Group == "Kiiro Custom Columns" ? field.InternalName : field.StaticName;
                            string name = KiiroDisplayNames.ContainsKey ( field.StaticName ) ? KiiroDisplayNames [ field.StaticName ] : field.Title;
                            ListItem item = new ListItem ( name, value );
                            item.Attributes.Add ( "ChildCssClass", childCssClass );
                            master.Items.Add ( item );
                        }
                    }
                }
            }
        }

        private string EnsureChildFilter ( SPField field )
        {
            string filterId = string.Empty;
            DropDownList filter = null;
            TextBox textValue = null;
            DropDownList dateValue = null;

            if ( !KiiroUserIdColumns.Contains ( field.StaticName ) )
            {
                switch ( field.Type )
                {
                    #region StringCompare
                    case SPFieldType.Text:
                    case SPFieldType.Note:
                    case SPFieldType.URL:
                        filter = ( DropDownList ) pnlFilters.FindControl ( "StringCompare" );
                        if ( filter == null )
                        {
                            filter = new DropDownList { ID = "StringCompare", CssClass = "StringCompare" };
                            filter.Items.Add ( new ListItem ( "Contains", "Contains" ) );
                            filter.Items.Add ( new ListItem ( "Starts With", "StartsWith" ) );
                            filter.Items.Add ( new ListItem ( "Ends With", "EndsWith" ) );
                            filter.Items.Add ( new ListItem ( "Is Empty/Null", "IsNull" ) );

                            foreach ( ListItem item in filter.Items )
                                if ( item.Value != "IsNull" )
                                    item.Attributes.Add ( "ChildCssClass", "TextValue" );

                            pnlFilters.Controls.Add ( filter );

                            textValue = ( TextBox ) pnlFilters.FindControl ( "TextValue" );
                            if ( textValue == null )
                                pnlFilters.Controls.Add ( new TextBox { ID = "TextValue", CssClass = "TextValue" } );
                        }
                        break;
                    #endregion
                    #region NumberCompare
                    case SPFieldType.Integer:
                    case SPFieldType.Number:
                    case SPFieldType.Currency:
                    case SPFieldType.Counter:
                        filter = ( DropDownList ) pnlFilters.FindControl ( "NumberCompare" );
                        if ( filter == null )
                        {
                            filter = new DropDownList { ID = "NumberCompare", CssClass = "NumberCompare" };
                            filter.Items.Add ( new ListItem ( "Equal To", "EqualTo" ) );
                            filter.Items.Add ( new ListItem ( "Greater Than", "GreaterThan" ) );
                            filter.Items.Add ( new ListItem ( "Less Than", "LessThan" ) );

                            foreach ( ListItem item in filter.Items )
                                if ( item.Value != "IsNull" )
                                    item.Attributes.Add ( "ChildCssClass", "TextValue" );

                            pnlFilters.Controls.Add ( filter );

                            textValue = ( TextBox ) pnlFilters.FindControl ( "TextValue" );
                            if ( textValue == null )
                                pnlFilters.Controls.Add ( new TextBox { ID = "TextValue", CssClass = "TextValue" } );
                        }
                        break;
                    #endregion
                    #region BooleanCompare
                    case SPFieldType.Boolean:
                        filter = ( DropDownList ) pnlFilters.FindControl ( "BooleanCompare" );
                        if ( filter == null )
                        {
                            filter = new DropDownList { ID = "BooleanCompare", CssClass = "BooleanCompare" };
                            filter.Items.Add ( new ListItem ( "True", "True" ) );
                            filter.Items.Add ( new ListItem ( "False", "False" ) );
                            filter.Items.Add ( new ListItem ( "Is Empty/Null", "IsNull" ) );
                        }
                        break;
                    #endregion
                    #region DateTimeCompare
                    case SPFieldType.DateTime:
                        filter = ( DropDownList ) pnlFilters.FindControl ( "DateTimeCompare" );
                        if ( filter == null )
                        {
                            filter = new DropDownList { ID = "DateTimeCompare", CssClass = "DateTimeCompare" };
                            filter.Items.Add ( new ListItem ( "In The Past", "InThePast" ) );
                            filter.Items.Add ( new ListItem ( "In The Future", "InTheFuture" ) );
                            filter.Items.Add ( new ListItem ( "In The Last...", "InTheLast" ) );
                            filter.Items.Add ( new ListItem ( "In The Next...", "InTheNext" ) );
                            filter.Items.Add ( new ListItem ( "Is Empty/Null", "IsNull" ) );

                            foreach ( ListItem item in filter.Items )
                                if ( item.Value == "InTheLast" || item.Value == "InTheNext" )
                                    item.Attributes.Add ( "ChildCssClass", "DateValue" );

                            pnlFilters.Controls.Add ( filter );

                            dateValue = ( DropDownList ) pnlFilters.FindControl ( "DateValue" );
                            if ( dateValue == null )
                            {
                                dateValue = new DropDownList { ID = "DateValue", CssClass = "DateValue" };
                                dateValue.Items.Add ( new ListItem ( "Day", "Day" ) );
                                dateValue.Items.Add ( new ListItem ( "Week", "Week" ) );
                                dateValue.Items.Add ( new ListItem ( "2 Weeks", "2Weeks" ) );
                                dateValue.Items.Add ( new ListItem ( "Month", "Month" ) );
                                dateValue.Items.Add ( new ListItem ( "2 Months", "2Months" ) );
                                dateValue.Items.Add ( new ListItem ( "3 Months", "3Months" ) );
                                dateValue.Items.Add ( new ListItem ( "6 Months", "6Months" ) );
                                dateValue.Items.Add ( new ListItem ( "Year", "Year" ) );

                                pnlFilters.Controls.Add ( dateValue );
                            }
                        }
                        break;
                    #endregion
                    #region InternalNameCompare
                    default: 
                        if ( field.StaticName == Constants.WorkFieldNames.Status )
                        {
                            filterId = "StatusCompare";
                            filter = ( DropDownList ) pnlFilters.FindControl ( filterId );

                            if ( filter == null )
                            {
                                filter = new DropDownList { ID = filterId, CssClass = filterId };
                                filter.Items.Add ( new ListItem ( "Completed", "Completed" ) );
                                filter.Items.Add ( new ListItem ( "In Progress", "InProgress" ) );
                                filter.Items.Add ( new ListItem ( "Not Started", "NotStarted" ) );
                                filter.Items.Add ( new ListItem ( "Open", "Open" ) );
                                filter.Items.Add ( new ListItem ( "On Hold", "OnHold" ) );
                                filter.Items.Add ( new ListItem ( "Closed", "Closed" ) );
                            }
                        }
                        else if ( field.StaticName == Constants.WorkFieldNames.WorkItemType )
                        {
                            filterId = "WorkItemTypeCompare";
                            filter = ( DropDownList ) pnlFilters.FindControl ( filterId );

                            if ( filter == null )
                            {
                                filter = new DropDownList { ID = filterId, CssClass = filterId };
                                filter.Items.Add ( new ListItem ( "Task", "Task" ) );
                                filter.Items.Add ( new ListItem ( "Issue", "Issue" ) );
                            }
                        }
                        else
                        {
                            filterId = string.Format ( "{0}Compare", field.InternalName );
                            filter = ( DropDownList ) pnlFilters.FindControl ( filterId );

                            if ( filter == null )
                            {
                                filter = new DropDownList { ID = filterId, CssClass = filterId };

                                List<string> values = new List<string> ( );
                                values = Entities.Select<BaseEntity, string> ( x => x.CustomFieldNamesAndValues [ field.Title ] ?? string.Empty ).ToList ( );

                                foreach ( string value in values )
                                {
                                    switch ( field.Type )
                                    {
                                        case SPFieldType.Lookup:
                                        case SPFieldType.User:
                                            // pairs
                                            List<string> pairs = FormattingHelpers.FieldTextToListOfStrings ( value );

                                            for ( int i = 0; i < pairs.Count - 1; i += 2 )
                                                if ( filter.Items.FindByValue ( pairs [ i ] ) == null )
                                                    filter.Items.Add ( new ListItem ( pairs [ i + 1 ], pairs [ i ] ) );
                                            break;

                                        case SPFieldType.Choice:
                                        case SPFieldType.MultiChoice:
                                            // singles
                                            List<string> singles = FormattingHelpers.FieldTextToListOfStrings ( value );

                                            foreach ( string single in singles )
                                                if ( filter.Items.FindByValue ( single ) == null )
                                                    filter.Items.Add ( new ListItem ( single, single ) );
                                            break;

                                        default:
                                            // discrete
                                            if ( filter.Items.FindByValue ( value ) == null )
                                                filter.Items.Add ( new ListItem ( value, value ) );
                                            break;
                                    }
                                }
                            }
                        }

                        if ( filter.Items.Count > 1 )
                            pnlFilters.Controls.Add ( filter );

                        break;
                    #endregion
                }
            }
            else
            {
                #region KiiroUserCompare
                filter = ( DropDownList ) pnlFilters.FindControl ( "KiiroUserCompare" );
                if ( filter == null )
                {
                    filter = new DropDownList { ID = "KiiroUserCompare", CssClass = "KiiroUserCompare" };

                    List<int> ids = new List<int> ( );
                    if ( EntityType == EntityType.Work )
                        foreach ( Work entity in Entities )
                            ids.AddRange ( entity.AssignedToList.FindAll ( id => !ids.Contains ( id ) ) );
                    else if ( EntityType == EntityType.Project )
                        foreach ( Project entity in Entities )
                            ids.AddRange ( entity.ProjectManagerIds.FindAll ( id => !ids.Contains ( id ) ) );

                    if ( ids.Count > 0 )
                        foreach ( User user in UserModel.GetUsersByIds ( ids, Base.SiteCollectionId, Base.ServerRelativeUrl ) )
                            filter.Items.Add ( new ListItem ( user.FullName, user.Id.ToString ( ) ) );

                    pnlFilters.Controls.Add ( filter );
                }
                #endregion
            }

            if ( filter != null )
                filterId = filter.CssClass;

            return filterId;
        }

        private void LoadFilterableColumns ( string contentTypeId )
        {
            List<SPField> fields = new List<SPField> ( );
            using ( SPWeb web = SPHelpers.GetPortalWeb ( Base.SiteCollectionId, Base.ServerRelativeUrl ) )
            {
                LoggingManager.LogMessage ( "INFO", string.Concat ( "Attempting to get content type for content type id: ", contentTypeId ) );
                
                SPContentType contentType = web.ContentTypes.Cast<SPContentType> ( )
                    .Where ( x => x.Id == new SPContentTypeId ( contentTypeId ) || x.Id.IsChildOf ( new SPContentTypeId ( contentTypeId ) ) )
                        .FirstOrDefault ( );

                if ( contentType == null )
                {
                    LoggingManager.LogMessage ( "WARNING", string.Concat ( "Content type not found in portal web for content type id: ", contentTypeId ) );
                    LoggingManager.LogMessage ( "INFO", string.Concat ( "Attempting to get root web content type for content type id: ", contentTypeId ) );
                    contentType = web.Site.RootWeb.ContentTypes.Cast<SPContentType> ( )
                        .Where ( x => x.Id == new SPContentTypeId ( contentTypeId ) || x.Id.IsChildOf ( new SPContentTypeId ( contentTypeId ) ) )
                            .FirstOrDefault ( );
                }

                if ( contentType != null )
                {
                    LoggingManager.LogMessage ( "INFO", string.Concat ( "Content type found: ", contentType.Name ) );
                    fields = contentType.Fields.Cast<SPField> ( ).ToList ( );
                }
                else
                {
                    LoggingManager.LogMessage ( "WARNING", string.Concat ( "Content type not found at portal web or root web for content type id: ", contentTypeId ) );
                }
            }

            List<string> defaultColumns = new List<string> ( );
            if ( contentTypeId == Constants.SPContentTypeIds.Work )
                defaultColumns = KiiroDefaultColumnsWork;
            else if ( contentTypeId == Constants.SPContentTypeIds.Project )
                defaultColumns = KiiroDefaultColumnsProject;

            if ( fields != null && fields.Count > 0 )
            {
                string temp = "";
                foreach ( SPField field in fields )
                    temp += temp != "" ? string.Concat ( ", ", field.StaticName ) : field.StaticName;

                LoggingManager.LogMessage ( "INFO", string.Concat ( "Attempting to get filterable columns from content type fields: ", temp ) );

                FilterableColumns = fields.Where ( x =>
                    x.Group == "Kiiro Custom Columns" || defaultColumns.Contains ( x.StaticName ) )
                        .ToList ( );

                temp = "";
                foreach ( SPField field in FilterableColumns )
                    temp += temp != "" ? string.Concat ( ", ", field.StaticName ) : field.StaticName;
                
                LoggingManager.LogMessage ( "INFO", string.Concat ( "Filterable columns are: ", temp ) );
            }
            else
            {
                LoggingManager.LogMessage ( "WARNING", "Content type fields were null or empty " );
            }
        }

        public List<BaseEntity> Apply ( )
        {
            LoadFilters ( );

            string name = Request.Params [ "Field" ];

            if ( !string.IsNullOrEmpty ( name ) && FilterableColumns != null )
            {
                bool specific = false;
                bool past = false;
                DateTime filterDate = DateTime.Now;

                SPField field = null;

                Dictionary<string, string> filters = new Dictionary<string, string> ( );
                List<string> values = Request.Params [ "Value" ].Split ( ";".ToCharArray ( ), StringSplitOptions.RemoveEmptyEntries ).ToList ( );
                foreach ( string value in values )
                {
                    string [ ] filter = value.Split ( ":".ToCharArray ( ), StringSplitOptions.RemoveEmptyEntries );
                    filters.Add ( filter [ 0 ], filter [ 1 ] );
                }

                if ( !KiiroDefaultColumnsProject.Contains ( name ) && !KiiroDefaultColumnsWork.Contains ( name ) )
                {
                    field = FilterableColumns.Where ( x => x.InternalName == name ).FirstOrDefault ( );
                    name = field.Title;

                    switch ( field.Type )
                    {
                        #region StringCompare
                        case SPFieldType.Text:
                        case SPFieldType.Note:
                        case SPFieldType.URL:
                            switch ( filters [ "StringCompare" ] )
                            {
                                case "Contains":
                                    Entities = Entities.Where (
                                        x => x.CustomFieldNamesAndValues.ContainsKey ( name ) &&
                                            x.CustomFieldNamesAndValues [ name ] != null &&
                                            x.CustomFieldNamesAndValues [ name ].Contains ( filters [ "TextValue" ] ) )
                                                .ToList ( );
                                    litAppliedFilter.Text = string.Format ( "{0} contains {1}", name, filters [ "TextValue" ] );
                                    break;
                                case "StartsWith":
                                    Entities = Entities.Where (
                                        x => x.CustomFieldNamesAndValues.ContainsKey ( name ) &&
                                            x.CustomFieldNamesAndValues [ name ] != null &&
                                            x.CustomFieldNamesAndValues [ name ].StartsWith ( filters [ "TextValue" ] ) )
                                                .ToList ( );
                                    litAppliedFilter.Text = string.Format ( "{0} starts with {1}", name, filters [ "TextValue" ] );
                                    break;
                                case "EndsWith":
                                    Entities = Entities.Where (
                                        x => x.CustomFieldNamesAndValues.ContainsKey ( name ) &&
                                            x.CustomFieldNamesAndValues [ name ] != null &&
                                            x.CustomFieldNamesAndValues [ name ].EndsWith ( filters [ "TextValue" ] ) )
                                                .ToList ( );
                                    litAppliedFilter.Text = string.Format ( "{0} ends with {1}", name, filters [ "TextValue" ] );
                                    break;
                                case "IsNull":
                                    Entities = Entities.Where (
                                        x => x.CustomFieldNamesAndValues.ContainsKey ( name ) &&
                                            x.CustomFieldNamesAndValues [ name ] != null &&
                                            string.IsNullOrEmpty ( x.CustomFieldNamesAndValues [ name ] ) )
                                                .ToList ( );
                                    litAppliedFilter.Text = string.Format ( "{0} is null or empty", name );
                                    break;
                                default:
                                    break;
                            }
                            break;
                        #endregion
                        #region NumberCompare
                        case SPFieldType.Integer:
                        case SPFieldType.Number:
                        case SPFieldType.Currency:
                        case SPFieldType.Counter:
                            switch ( filters [ "NumberCompare" ] )
                            {
                                case "EqualTo":
                                    Entities = Entities.Where (
                                        x => x.CustomFieldNamesAndValues.ContainsKey ( name ) &&
                                            x.CustomFieldNamesAndValues [ name ] != null &&
                                            int.Parse ( x.CustomFieldNamesAndValues [ name ] ) == int.Parse ( filters [ "TextValue" ] ) )
                                                .ToList ( );
                                    litAppliedFilter.Text = string.Format ( "{0} is equal to {1}", name, filters [ "TextValue" ] );
                                    break;
                                case "GreaterThan":
                                    Entities = Entities.Where (
                                        x => x.CustomFieldNamesAndValues.ContainsKey ( name ) &&
                                            x.CustomFieldNamesAndValues [ name ] != null &&
                                            int.Parse ( x.CustomFieldNamesAndValues [ name ] ) > int.Parse ( filters [ "TextValue" ] ) )
                                                .ToList ( );
                                    litAppliedFilter.Text = string.Format ( "{0} is greater than {1}", name, filters [ "TextValue" ] );
                                    break;
                                case "LessThan":
                                    Entities = Entities.Where (
                                        x => x.CustomFieldNamesAndValues.ContainsKey ( name ) &&
                                            x.CustomFieldNamesAndValues [ name ] != null &&
                                            int.Parse ( x.CustomFieldNamesAndValues [ name ] ) < int.Parse ( filters [ "TextValue" ] ) )
                                                .ToList ( );
                                    litAppliedFilter.Text = string.Format ( "{0} is less than {1}", name, filters [ "TextValue" ] );
                                    break;
                                case "IsNull":
                                    Entities = Entities.Where (
                                        x => x.CustomFieldNamesAndValues.ContainsKey ( name ) &&
                                            x.CustomFieldNamesAndValues [ name ] != null &&
                                            string.IsNullOrEmpty ( x.CustomFieldNamesAndValues [ name ] ) )
                                                .ToList ( );
                                    litAppliedFilter.Text = string.Format ( "{0} is null or empty", name );
                                    break;
                                default:
                                    break;
                            }
                            break;
                        #endregion
                        #region BooleanCompare
                        case SPFieldType.Boolean:
                            switch ( filters [ "BooleanCompare" ] )
                            {
                                case "True":
                                case "False":
                                    Entities = Entities.Where (
                                        x => x.CustomFieldNamesAndValues.ContainsKey ( name ) &&
                                            x.CustomFieldNamesAndValues [ name ] != null &&
                                            bool.Parse ( x.CustomFieldNamesAndValues [ name ] ) == bool.Parse ( filters [ "BooleanCompare" ] ) )
                                                .ToList ( );
                                    litAppliedFilter.Text = string.Format ( "{0} is {1}", name, filters [ "BooleanCompare" ] );
                                    break;
                                case "IsNull":
                                    Entities = Entities.Where (
                                        x => x.CustomFieldNamesAndValues.ContainsKey ( name ) &&
                                            x.CustomFieldNamesAndValues [ name ] != null &&
                                            string.IsNullOrEmpty ( x.CustomFieldNamesAndValues [ name ] ) )
                                                .ToList ( );
                                    litAppliedFilter.Text = string.Format ( "{0} is null or empty", name );
                                    break;
                                default:
                                    break;
                            }
                            break;
                        #endregion
                        #region DateTimeCompare
                        case SPFieldType.DateTime:
                            specific = filters [ "DateTimeCompare" ] == "InTheLast" || filters [ "DateTimeCompare" ] == "InTheNext";
                            past = filters [ "DateTimeCompare" ] == "InThePast" || filters [ "DateTimeCompare" ] == "InTheLast";

                            filterDate = GetFilterDate ( specific, past, filters );

                            if ( past )
                                Entities = Entities.Where (
                                    x => x.CustomFieldNamesAndValues.ContainsKey ( name ) &&
                                        x.CustomFieldNamesAndValues [ name ] != null &&
                                        DateTime.Parse ( x.CustomFieldNamesAndValues [ name ] ) >= filterDate.Date &&
                                        DateTime.Parse ( x.CustomFieldNamesAndValues [ name ] ) <= DateTime.Now.Date )
                                            .ToList ( );
                            else
                                Entities = Entities.Where (
                                    x => x.CustomFieldNamesAndValues.ContainsKey ( name ) &&
                                        x.CustomFieldNamesAndValues [ name ] != null &&
                                        DateTime.Parse ( x.CustomFieldNamesAndValues [ name ] ) <= filterDate.Date &&
                                        DateTime.Parse ( x.CustomFieldNamesAndValues [ name ] ) >= DateTime.Now.Date )
                                            .ToList ( );

                            litAppliedFilter.Text = string.Format ( "{0} is {1}", name,
                                ( ( DropDownList ) pnlFilters.FindControl ( "DateTimeCompare" ) ).Items.FindByValue ( filters [ "DateTimeCompare" ] ).Text.Replace ( "...", "" ) );

                            if ( specific )
                                litAppliedFilter.Text += string.Format ( " {0}",
                                    ( ( DropDownList ) pnlFilters.FindControl ( "DateValue" ) ).Items.FindByValue ( filters [ "DateValue" ] ).Text );
                            break;
                        #endregion
                        #region InternalNameCompare
                        default:
                            Entities = Entities.Where (
                                x => x.CustomFieldNamesAndValues.ContainsKey ( name ) &&
                                    x.CustomFieldNamesAndValues [ name ] != null &&
                                    x.CustomFieldNamesAndValues [ name ].Split ( "#;".ToCharArray ( ) )
                                        .Contains ( filters [ field.InternalName + "Compare" ] ) )
                                            .ToList ( );
                            litAppliedFilter.Text = string.Format ( "{0} is {1}", name, filters [ field.InternalName + "Compare" ] );
                            break;
                        #endregion
                    }
                }
                #region WorkDefaultColumns
                else if ( KiiroDefaultColumnsWork.Contains ( name ) )
                {
                    switch ( name )
                    {
                        case Constants.WorkFieldNames.AssignedToList:
                            Entities = Entities.Cast<Work> ( ).Where (
                                x => x.AssignedToList.Contains ( int.Parse ( filters [ "KiiroUserCompare" ] ) ) )
                                    .Cast<BaseEntity> ( ).ToList ( );

                            litAppliedFilter.Text = string.Format ( "Is assigned to {0}",
                                ( ( DropDownList ) pnlFilters.FindControl ( "KiiroUserCompare" ) ).Items.FindByValue ( filters [ "KiiroUserCompare" ] ).Text );
                            break;
                        case Constants.WorkFieldNames.EndDate:
                            specific = filters [ "DateTimeCompare" ] == "InTheLast" || filters [ "DateTimeCompare" ] == "InTheNext";
                            past = filters [ "DateTimeCompare" ] == "InThePast" || filters [ "DateTimeCompare" ] == "InTheLast";

                            filterDate = GetFilterDate ( specific, past, filters );
                            if ( past )
                                Entities = Entities.Cast<Work> ( ).Where (
                                    x => x.EndDate.Date >= filterDate.Date && x.EndDate.Date <= DateTime.Now.Date )
                                        .Cast<BaseEntity> ( ).ToList ( );
                            else
                                Entities = Entities.Cast<Work> ( ).Where (
                                    x => x.EndDate.Date <= filterDate.Date && x.EndDate.Date >= DateTime.Now.Date )
                                        .Cast<BaseEntity> ( ).ToList ( );

                            litAppliedFilter.Text = string.Format ( "End Date is {0}",
                                ( ( DropDownList ) pnlFilters.FindControl ( "DateTimeCompare" ) ).Items.FindByValue ( filters [ "DateTimeCompare" ] ).Text.Replace ( "...", "" ) );

                            if ( specific )
                                litAppliedFilter.Text += string.Format ( " {0}",
                                    ( ( DropDownList ) pnlFilters.FindControl ( "DateTimeValue" ) ).Items.FindByValue ( filters [ "DateTimeValue" ] ).Text );
                            break;
                        case Constants.WorkFieldNames.StartDate:
                            specific = filters [ "DateTimeCompare" ] == "InTheLast" || filters [ "DateTimeCompare" ] == "InTheNext";
                            past = filters [ "DateTimeCompare" ] == "InThePast" || filters [ "DateTimeCompare" ] == "InTheLast";

                            filterDate = GetFilterDate ( specific, past, filters );
                            if ( past )
                                Entities = Entities.Cast<Work> ( ).Where (
                                    x => x.StartDate.Date >= filterDate.Date && x.StartDate.Date <= DateTime.Now.Date )
                                        .Cast<BaseEntity> ( ).ToList ( );
                            else
                                Entities = Entities.Cast<Work> ( ).Where (
                                    x => x.StartDate.Date <= filterDate.Date && x.StartDate.Date >= DateTime.Now.Date )
                                        .Cast<BaseEntity> ( ).ToList ( );

                            litAppliedFilter.Text = string.Format ( "Start Date is {0}",
                                ( ( DropDownList ) pnlFilters.FindControl ( "DateTimeCompare" ) ).Items.FindByValue ( filters [ "DateTimeCompare" ] ).Text.Replace ( "...", "" ) );

                            if ( specific )
                                litAppliedFilter.Text += string.Format ( " {0}",
                                    ( ( DropDownList ) pnlFilters.FindControl ( "DateValue" ) ).Items.FindByValue ( filters [ "DateValue" ] ).Text );
                            break;
                        case Constants.WorkFieldNames.Status:
                            Entities = Entities.Cast<Work> ( ).Where (
                                x => x.Status == ( StatusType ) Enum.Parse ( typeof ( StatusType ), filters [ "StatusCompare" ] ) )
                                    .Cast<BaseEntity> ( ).ToList ( );

                            litAppliedFilter.Text = string.Format ( "Status is {0}", 
                                ( ( DropDownList ) pnlFilters.FindControl ( "StatusCompare" ) ).Items.FindByValue ( filters [ "StatusCompare" ] ).Text );
                            break;
                        case Constants.WorkFieldNames.WorkItemType:
                            Entities = Entities.Cast<Work> ( ).Where (
                                x => x.WorkItemType == ( WorkType ) Enum.Parse ( typeof ( WorkType ), filters [ "WorkItemTypeCompare" ] ) )
                                    .Cast<BaseEntity> ( ).ToList ( );

                            litAppliedFilter.Text = string.Format ( "Type is {0}",  
                                ( ( DropDownList ) pnlFilters.FindControl ( "WorkItemTypeCompare" ) ).Items.FindByValue ( filters [ "WorkItemTypeCompare" ] ).Text );
                            break;
                        default:
                            break;
                    }
                }
                #endregion
                #region ProjectDefaultColumns
                else if ( KiiroDefaultColumnsProject.Contains ( name ) )
                {
                    switch ( name )
                    {
                        case Constants.ProjectFieldNames.ProjectManagerIds:
                            Entities = Entities.Cast<Project> ( ).Where (
                                x => x.ProjectManagerIds.Contains ( int.Parse ( filters [ "KiiroUserCompare" ] ) ) )
                                    .Cast<BaseEntity> ( ).ToList ( );

                            litAppliedFilter.Text = string.Format ( "Project managers contain {0}",
                                ( ( DropDownList ) pnlFilters.FindControl ( "KiiroUserCompare" ) ).Items.FindByValue ( filters [ "KiiroUserCompare" ] ).Text );
                            break;
                        case Constants.ProjectFieldNames.EndDate:
                            specific = filters [ "DateTimeCompare" ] == "InTheLast" || filters [ "DateTimeCompare" ] == "InTheNext";
                            past = filters [ "DateTimeCompare" ] == "InThePast" || filters [ "DateTimeCompare" ] == "InTheLast";

                            filterDate = GetFilterDate ( specific, past, filters );
                            if ( past )
                                Entities = Entities.Cast<Project> ( ).Where (
                                    x => x.EndDate.Date >= filterDate.Date && x.EndDate.Date <= DateTime.Now.Date )
                                        .Cast<BaseEntity> ( ).ToList ( );
                            else
                                Entities = Entities.Cast<Project> ( ).Where (
                                    x => x.EndDate.Date <= filterDate.Date && x.EndDate.Date >= DateTime.Now.Date )
                                        .Cast<BaseEntity> ( ).ToList ( );

                            litAppliedFilter.Text = string.Format ( "End Date is {0}",
                                ( ( DropDownList ) pnlFilters.FindControl ( "DateTimeCompare" ) ).Items.FindByValue ( filters [ "DateTimeCompare" ] ).Text.Replace ( "...", "" ) );

                            if ( specific )
                                litAppliedFilter.Text += string.Format ( " {0}",
                                    ( ( DropDownList ) pnlFilters.FindControl ( "DateValue" ) ).Items.FindByValue ( filters [ "DateValue" ] ).Text );
                            break;
                        case Constants.ProjectFieldNames.StartDate:
                            specific = filters [ "DateTimeCompare" ] == "InTheLast" || filters [ "DateTimeCompare" ] == "InTheNext";
                            past = filters [ "DateTimeCompare" ] == "InThePast" || filters [ "DateTimeCompare" ] == "InTheLast";

                            filterDate = GetFilterDate ( specific, past, filters );
                            if ( past )
                                Entities = Entities.Cast<Project> ( ).Where (
                                    x => x.StartDate.Date >= filterDate.Date && x.StartDate.Date <= DateTime.Now.Date )
                                        .Cast<BaseEntity> ( ).ToList ( );
                            else
                                Entities = Entities.Cast<Project> ( ).Where (
                                    x => x.StartDate.Date <= filterDate.Date && x.StartDate.Date >= DateTime.Now.Date )
                                        .Cast<BaseEntity> ( ).ToList ( );

                            litAppliedFilter.Text = string.Format ( "Start Date is {0}",
                                ( ( DropDownList ) pnlFilters.FindControl ( "DateTimeCompare" ) ).Items.FindByValue ( filters [ "DateTimeCompare" ] ).Text.Replace ( "...", "" ) );

                            if ( specific )
                                litAppliedFilter.Text += string.Format ( " {0}",
                                    ( ( DropDownList ) pnlFilters.FindControl ( "DateValue" ) ).Items.FindByValue ( filters [ "DateValue" ] ).Text );
                            break;
                        default:
                            break;
                    }
                }
                #endregion
            }

            if ( litAppliedFilter.Text != "" )
                unfiltered.Style.Add ( "display", "none" );
            else
                filtered.Style.Add ( "display", "none" );

            return Entities;
        }

        private DateTime GetFilterDate ( bool specific, bool past, Dictionary<string, string> filters )
        {
            DateTime filterDate = DateTime.Now;

            if ( specific )
            {
                switch ( filters [ "DateValue" ] )
                {
                    case "Day":
                        filterDate = filterDate.AddDays ( past ? -1 : 1 );
                        break;
                    case "Week":
                        filterDate = filterDate.AddDays ( past ? -7 : 7 );
                        break;
                    case "2Weeks":
                        filterDate = filterDate.AddDays ( past ? -14 : 14 );
                        break;
                    case "Month":
                        filterDate = filterDate.AddMonths ( past ? -1 : 1 );
                        break;
                    case "2Months":
                        filterDate = filterDate.AddMonths ( past ? -2 : 2 );
                        break;
                    case "3Months":
                        filterDate = filterDate.AddMonths ( past ? -3 : 3 );
                        break;
                    case "6Months":
                        filterDate = filterDate.AddMonths ( past ? -6 : 6 );
                        break;
                    case "Year":
                        filterDate = filterDate.AddYears ( past ? -1 : 1 );
                        break;
                }
            }
            else
                filterDate = past ? DateTime.MinValue : DateTime.MaxValue;

            return filterDate;
        }
    }
}

/*************************************************************************
 * 
 * $Log: /Internal Projects/Kiiro/Kiiro.SiteDefinition/12/TEMPLATE/CONTROLTEMPLATES/Kiiro/Filter.ascx.cs $
 * 
 * 8     4/07/10 2:33p Camerons
 * 
 * 7     2/09/10 12:48p Camerons
 * 
 * 6     2/08/10 12:00p Camerons
 * 
 * 5     1/27/10 4:29p Camerons
 * 
 * 4     1/25/10 6:10p Camerons
 * 
 * 3     1/14/10 12:46p Camerons
 * 
 **************************************************************************/